package com.huawei.translate.provider;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.huawei.translate.config.HttpProxyConfiguration;
import com.huawei.translate.utils.HttpUtils;
import com.huawei.translate.utils.SystemConfig;
import com.huawei.translate.vo.translate.TranslateRequest;
import com.huawei.translate.vo.translate.TranslateResponse;
import com.huawei.translate.vo.translate.YoudaoResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;

@Service
public class YoudaoTranslateProvider implements TranslateProvider {

    private static final Logger LOG = Logger.getLogger(YoudaoTranslateProvider.class);

    @Autowired
    private HttpProxyConfiguration proxyConfig;

    @Override
    public TranslateResponse translate(TranslateRequest request) {
        try {
            long startTime = System.currentTimeMillis();
            LOG.info("translate, going to create http client with proxy host: " + proxyConfig.getProxyHost());

            YoudaoResponse youdaoResponse = sendTranslateRequest(request.getText());

            LOG.info("Receive Response from YouDao:" + (System.currentTimeMillis() - startTime));

            if (!"0".equals(youdaoResponse.getErrorCode())) {
                LOG.error("Request:" + request.toString() + "\t errorCode" + youdaoResponse.getErrorCode());
            }
            LOG.info("Receive response translate from youdao." + youdaoResponse.getTranslation()[0]);

            return new TranslateResponse(HttpStatus.OK.value(), youdaoResponse.getTranslation()[0]);
        } catch (Exception e) {
            LOG.info("Error response translate from youdao.");
            LOG.error(e.getMessage(), e);
            return null;
        }
    }

    @Override
    public String translate(String from, String to, String content, String key) {
        try {
            YoudaoResponse youdaoResponse = sendTranslateRequest(content);

            if (!"0".equals(youdaoResponse.getErrorCode())) {
                return null;
            }

            return youdaoResponse.getTranslation()[0];
        } catch (Exception e) {
            return null;
        }

    }

    private YoudaoResponse sendTranslateRequest(String text) throws URISyntaxException, IOException {

        CloseableHttpClient httpClient = HttpUtils.makeHttpClient(proxyConfig.getProxyHost(), proxyConfig.getProxyPort(), proxyConfig.getProxyUserName(), proxyConfig.getProxyPassword());

        LOG.info("Receive request to translate from youdao.");

        URIBuilder builder = new URIBuilder(SystemConfig.getProperty("youdao.translate"));
        builder.setParameter("key", SystemConfig.getProperty("youdao.key"))
                .setParameter("q", text)
                .setParameter("type", "data")
                .setParameter("doctype", "json")
                .setParameter("only", "translate")
                .setParameter("model", "nmt");

        HttpGet httpGet = new HttpGet(builder.build());

        httpGet.setConfig(setTimeoutConfig());

        LOG.info("Start request translate to youdao." + httpGet.getURI());
        CloseableHttpResponse response = httpClient.execute(httpGet);

        InputStream inputStream = response.getEntity().getContent();
        String content = HttpUtils.getContentFromInputStream(inputStream);

        LOG.info("TranslateResult:" + content);
        return parseJson(content);
    }

    @Override
    public String toDescription() {
        return TranslateProviderType.YouDao.getDescription();
    }

    private YoudaoResponse parseJson(String json) {
        GsonBuilder gsonBuilder = new GsonBuilder();
        Gson gson = gsonBuilder.create();

        return gson.fromJson(json, YoudaoResponse.class);
    }

    public RequestConfig setTimeoutConfig() {
        int timeOut = Integer.parseUnsignedInt(SystemConfig.getProperty("route.youdao.timeout", "2000"));
        return RequestConfig.custom().setSocketTimeout(timeOut).setConnectTimeout(timeOut)
                .build();
    }
}
